package cn.kinoko.common.utils;


import cn.kinoko.common.constant.HeaderConstant;
import jakarta.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * 获取用户访问ip地址工具类
 */
public class RequestUtil {

    /**
     * 主要功能:获取请求方IP
     * 注意事项:无
     *
     * @param request 请求
     * @return String IP
     */
    public static String getIpAddress(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");  
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");  
        }  
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");  
        }  
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");  
        }  
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");  
        }  
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();  
        }
        // 获取到多个ip时取第一个作为客户端真实ip
        if (StringUtils.isNotEmpty(ip) && ip.contains(",")) {
        	String[] ipArray = ip.split(",");
        	if (ArrayUtils.isNotEmpty(ipArray)) {
        		ip = ipArray[0];
        	}
        }
        return ip;  
    }

    /**
     * 将request查询参数封装至Map
     *
     * @param request  请求
     * @return 参数Map
     */
    public static Map<String, Object> getParameters(HttpServletRequest request) {
        Enumeration<String> names = request.getParameterNames();
        Map<String, Object> map = new HashMap<>(16);
        while (names.hasMoreElements()) {
            String key = names.nextElement();
            String value = request.getParameter(key);
            map.put(key, value);
        }
        return map;
    }

    /**
     * 获取完整的请求URL
     *
     * @param request 请求
     * @return URL
     */
    public static String getRequestUrl(HttpServletRequest request) {
        return request.getRequestURL().toString();
    }

    /**
     * 主要功能:获取request
     * 注意事项:无
     *
     * @return HttpServletRequest
     */
    public static HttpServletRequest getCurrentRequest() {
        return ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
    }

    /**
     * 主要功能:获取request IP
     * 注意事项:无
     *
     * @return HttpServletRequest
     */
    public static String getCurrentRequestIp() {
        return getIpAddress(getCurrentRequest());
    }

    public static <T> T getRequestAttr(String name) {
        @SuppressWarnings("unchecked")
        T v = (T) Objects.requireNonNull(RequestContextHolder.getRequestAttributes()).getAttribute(name, 1);
        return v;
    }

    public static <T> void setRequestAttr(String name, T v) {
        Objects.requireNonNull(RequestContextHolder.getRequestAttributes()).setAttribute(name, v, 1);
    }

    public static Long getUid() {
        String uid = getCurrentRequest().getHeader(HeaderConstant.UID_HEADER);
        try {
            return Long.valueOf(uid);
        } catch (Exception e) {
            return null;
        }
    }
}

